use glass::Reflect;
use serde::{Deserialize, Serialize};
use serde_json::Value;

use super::Generator;

macro_rules! def_number_range_generator {
    ($ident: ident, $ty: ty) => {
        #[derive(Debug, Default, Reflect, Serialize, Deserialize)]
        pub struct $ident {
            #[name("最小值")]
            pub min: Option<$ty>,

            #[name("最大值")]
            pub max: Option<$ty>,
        }

        impl Generator for $ident {
            fn generate(&self) -> Value {
                let min = self.min.unwrap_or(<$ty>::MIN);
                let max = self.max.unwrap_or(<$ty>::MAX);
                let value = rand::random_range(min..=max);
                Value::from(value)
            }
        }
    };
}

def_number_range_generator!(RangeI8Generator, i8);
def_number_range_generator!(RangeI16Generator, i16);
def_number_range_generator!(RangeI32Generator, i32);
def_number_range_generator!(RangeI64Generator, i64);
def_number_range_generator!(RangeU8Generator, u8);
def_number_range_generator!(RangeU16Generator, u16);
def_number_range_generator!(RangeU32Generator, u32);
def_number_range_generator!(RangeU64Generator, u64);
def_number_range_generator!(RangeUsizeGenerator, usize);
def_number_range_generator!(RangeF32Generator, f32);
def_number_range_generator!(RangeF64Generator, f64);

#[derive(Debug, Default, Reflect, Serialize, Deserialize)]
pub struct RangeIsizeGenerator {
    #[name("最小值")]
    pub min: Option<isize>,

    #[name("最大值")]
    pub max: Option<isize>,
}

impl Generator for RangeIsizeGenerator {
    fn generate(&self) -> Value {
        let min = self.min.unwrap_or(isize::MIN) as i64;
        let max = self.max.unwrap_or(isize::MAX) as i64;
        let value = rand::random_range(min..=max);
        Value::from(value)
    }
}
